import zlib from "zlib";
import fs from "fs";

/**
 * @class
 * @param {number} id - The sound effect/folder ID.
 * @param {string} name - The sound effect/folder name.
 * @param {boolean} isFolder - Whether this is a sound effect or folder.
 * @param {number} parentFolder - The id of the parent folder.
 * @param {number} filesize - The sound effect file size in bytes.
 * @param {number} duration - The duration of the sound effect, in `seconds * 100`
 */
class SoundEffect {
  constructor(id, name, isFolder, parentFolder, filesize, duration) {
    this.id = parseInt(id);
    this.name = name;
    this.isFolder = isFolder !== "0";
    this.parentFolder = parseInt(parentFolder);
    this.filesize = parseInt(filesize);
    this.duration = parseInt(duration);
  }
}

async function getSfxLibraryData() {
  const url = "https://geometrydashfiles.b-cdn.net/sfx/sfxlibrary.dat";

  if (fs.existsSync("cache/sfxlibrary.dat")) {
    return fs.readFileSync("cache/sfxlibrary.dat", "utf-8");
  }

  if (!fs.existsSync("cache")) {
    fs.mkdirSync("cache")
  }

  try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`Response staus: ${response.status}`);
    }

    const rawSfxData = await response.text();
    fs.writeFileSync("cache/sfxlibrary.dat", rawSfxData);
    return rawSfxData;
  } catch (error) {
    console.error(error.message);
  }
}

function decodeSfxLibraryData(rawSfxData) {
  const rawSfxDataBuffer = Buffer.from(rawSfxData, "base64url");
  const sfxData = zlib.inflateSync(rawSfxDataBuffer).toString();

  return sfxData;
}

function parseSfxFiles(sfxFiles) {
  let sfx = sfxFiles.split(";");
  sfx.pop();

  sfx = sfx.map((el) => el.split(","));
  sfx = sfx.map((el) => new SoundEffect(...el));

  return sfx;
}

const rawSfxData = await getSfxLibraryData();
const decodedSfxLibraryData = decodeSfxLibraryData(rawSfxData).split("|");

const sfxFiles = decodedSfxLibraryData[0];
const sfxCredits = decodedSfxLibraryData[1];

export const parsedSfxFiles = parseSfxFiles(sfxFiles);
